package photorganizer.common.logging;

import java.util.logging.Level;

import photorganizer.common.bean.BeanHome;
import photorganizer.common.helper.StackTraceHelper;

public class StandardLogger implements Logger, Tracer {

	private static final int INITIAL_BUFFER_LENGTH = 250;

	/* (non-Javadoc)
	 * @see photorganizer.common.logging.Logger#severe(java.lang.Object[])
	 */
	public void severe(Object... messageParts) {
		log(Level.SEVERE, messageParts);
	}

	/* (non-Javadoc)
	 * @see photorganizer.common.logging.Logger#warning(java.lang.Object[])
	 */
	public void warning(Object... messageParts) {
		log(Level.WARNING, messageParts);
	}

	/* (non-Javadoc)
	 * @see photorganizer.common.logging.Logger#info(java.lang.Object[])
	 */
	public void info(Object... messageParts) {
		log(Level.INFO, messageParts);
	}

	/* (non-Javadoc)
	 * @see photorganizer.common.logging.Logger#config(java.lang.Object[])
	 */
	public void config(Object... messageParts) {
		log(Level.CONFIG, messageParts);
	}

	/* (non-Javadoc)
	 * @see photorganizer.common.logging.Logger#fine(java.lang.Object[])
	 */
	public void fine(Object... messageParts) {
		log(Level.FINE, messageParts);
	}

	/* (non-Javadoc)
	 * @see photorganizer.common.logging.Tracer#entering(java.lang.String, java.lang.String, java.lang.Object[])
	 */
	public void entering(String sourceClass, String sourceMethod, Object[] parameters) {
		log(Level.FINER, sourceClass, sourceMethod, "ENTRY ", parameters);
	}

	/* (non-Javadoc)
	 * @see photorganizer.common.logging.Tracer#exiting(java.lang.String, java.lang.String)
	 */
	public void exiting(String sourceClass, String sourceMethod) {
		log(Level.FINER, sourceClass, sourceMethod, "RETURN");
	}

	/* (non-Javadoc)
	 * @see photorganizer.common.logging.Tracer#exiting(java.lang.String, java.lang.String, java.lang.Object)
	 */
	public void exiting(String sourceClass, String sourceMethod, Object result) {
		log(Level.FINER, sourceClass, sourceMethod, "RETURN ", result);
	}

	/* (non-Javadoc)
	 * @see photorganizer.common.logging.Tracer#throwing(java.lang.String, java.lang.String, java.lang.Throwable)
	 */
	public void throwing(String sourceClass, String sourceMethod, Throwable throwable) {
		log(Level.FINER, sourceClass, sourceMethod, "THROW ", throwable);
	}

	private void log(Level level, Object... messageParts) {
		StackTraceElement stackTraceElement = StackTraceHelper.getInvokingStackTraceElement(Logger.class.getPackage());
		log(level, stackTraceElement.getClassName(), stackTraceElement.getMethodName(), null, messageParts);
	}

	private void log(Level level, String sourceClass, String sourceMethod, String pre, Object... messageParts) {
		java.util.logging.Logger logger = java.util.logging.Logger.getLogger(sourceClass);
		if (logger.isLoggable(level)) {
			StringBuilder message = new StringBuilder(INITIAL_BUFFER_LENGTH);
			Dumper dumper = BeanHome.get(Dumper.class);
			if (pre != null) {
				dumper.dump(message, pre);
			}
			if (messageParts != null) {
				for (Object messagePart : messageParts) {
					dumper.dump(message, messagePart);
				}
			}
			logger.logp(level, sourceClass, sourceMethod, message.toString());
		}
	}

}
